home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / games / nhak_src.zip / TRAP.C < prev    next >
C/C++ Source or Header  |  1993-03-16  |  45KB  |  1,881 lines

  1. /*    SCCS Id: @(#)trap.c    3.0    89/11/20
  2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3. /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5. #include    "hack.h"
  6. #include    "edog.h"
  7.  
  8. #ifdef OVLB
  9.  
  10. const char *traps[] = {
  11.     "",
  12.     " monster trap",
  13.     " statue trap",
  14.     " bear trap",
  15.     "n arrow trap",
  16.     " dart trap",
  17.     " trapdoor",
  18.     " teleportation trap",
  19.     " pit",
  20.     " sleeping gas trap"
  21.     ," magic trap"
  22.     ," squeaky board"
  23.     ," web"
  24.     ," spiked pit"
  25.     ," level teleporter"
  26. #ifdef SPELLS
  27.     ,"n anti-magic field" 
  28. #endif
  29.     ," rust trap"
  30. #ifdef POLYSELF
  31.     ," polymorph trap"
  32. #endif
  33.     ," land mine"
  34. };
  35.  
  36. #endif /* OVLB */
  37.  
  38. void NDECL(domagictrap);
  39. STATIC_DCL boolean FDECL(thitm, (int, struct monst *, struct obj *, int));
  40.  
  41. #ifdef OVLB
  42.  
  43. static void NDECL(vtele);
  44.  
  45. /* Generic rust-armor function.  Returns TRUE if a message was printed;
  46.  * "print", if set, means to print a message (and thus to return TRUE) even
  47.  * if the item could not be rusted; otherwise a message is printed and TRUE is
  48.  * returned only for rustable items.
  49.  */
  50. boolean
  51. rust_dmg(otmp, ostr, type, print)
  52. register struct obj *otmp;
  53. register const char *ostr;
  54. int type;
  55. boolean print;
  56. {
  57.     static const char NEARDATA *gook[] = { "slag", "rust", "rot", "corrosion" };
  58.     static const char NEARDATA *action[] = { "smolder", "rust", "rot", "corrode" };
  59.     static const char NEARDATA *msg[] =  { "burnt", "rusted", "rotten", "corroded" };
  60.     boolean vulnerable = FALSE;
  61.     boolean plural;
  62.  
  63.     if (!otmp) return(FALSE);
  64.     switch(type) {
  65.         case 0:
  66.         case 2: vulnerable = is_flammable(otmp); break;
  67.         case 1: vulnerable = is_rustprone(otmp); break;
  68.         case 3: vulnerable = is_corrodeable(otmp); break;
  69.     }
  70.  
  71.     if (!print && (!vulnerable || otmp->rustfree || otmp->spe < -2))
  72.         return FALSE;
  73.  
  74.     plural = is_gloves(otmp) || is_boots(otmp);
  75.  
  76.     if (!vulnerable)
  77.         Your("%s %s not affected!", ostr, plural ? "are" : "is");
  78.     else if (otmp->spe >= -2) {
  79.         if (otmp->rustfree)
  80.             pline("The %s on your %s vanishes instantly!",
  81.                         gook[type], ostr);
  82.         else if (otmp->blessed && !rnl(4))
  83.             pline("Somehow, your %s %s not affected!", ostr,
  84.                     plural ? "are" : "is");
  85.         else {
  86.             Your("%s %s%s!", ostr, action[type],
  87.                 plural ? "" : "s");
  88.             otmp->spe--;
  89.             adj_abon(otmp, -1);
  90.         }
  91.     } else Your("%s %s%s quite %s.", ostr, Blind ? "feel" : "look",
  92.                          plural ? "" : "s", msg[type]);
  93.     return(TRUE);
  94. }
  95.  
  96. struct trap *
  97. maketrap(x,y,typ)
  98. register int x, y, typ;
  99. {
  100.     register struct trap *ttmp;
  101.     register struct permonst *ptr;
  102.  
  103.     if (ttmp = t_at(x,y)) {
  104.         if (u.utrap &&
  105.           ((u.utraptype == TT_BEARTRAP && typ != BEAR_TRAP) ||
  106.           (u.utraptype == TT_WEB && typ != WEB) ||
  107.           (u.utraptype == TT_PIT && typ != PIT && typ != SPIKED_PIT)))
  108.             u.utrap = 0;
  109.         ttmp->ttyp = typ;
  110.         return ttmp;
  111.     }
  112.     ttmp = newtrap();
  113.     ttmp->ttyp = typ;
  114.     ttmp->tx = x;
  115.     ttmp->ty = y;
  116.     switch(typ) {
  117.         case MONST_TRAP:        /* create a monster in "hiding" */
  118.         {    int tryct = 0;
  119.         if(rn2(5) && (ptr = mkclass(S_PIERCER)))
  120.             ttmp->pm = monsndx(ptr);
  121.         else do {
  122.             ttmp->pm = rndmonnum();
  123.         } while ((noattacks(&mons[ttmp->pm]) ||
  124.             !mons[ttmp->pm].mmove) && ++tryct < 100);
  125.         if (tryct == 100) {
  126.             free((genericptr_t)ttmp);
  127.             return(struct trap *)0;
  128.         }
  129.         break;
  130.         }
  131.         case STATUE_TRAP:        /* create a "living" statue */
  132.         ttmp->pm = rndmonnum();
  133.         (void) mkcorpstat(STATUE, &mons[ttmp->pm], x, y);
  134.         break;
  135.         default:
  136.         ttmp->pm = -1;
  137.         break;
  138.     }
  139.     ttmp->tseen = 0;
  140.     ttmp->once = 0;
  141.     ttmp->ntrap = ftrap;
  142.     ftrap = ttmp;
  143.     return(ttmp);
  144. }
  145.  
  146. int
  147. teleok(x, y)
  148. register int x, y;
  149. {                /* might throw him into a POOL
  150.                  * removed by GAN 10/20/86
  151.                  */
  152. #ifdef STUPID
  153.     boolean    tmp1, tmp2, tmp3;
  154. #  ifdef POLYSELF
  155.     tmp1 = isok(x,y) && (!IS_ROCK(levl[x][y].typ) ||
  156.         passes_walls(uasmon)) && !MON_AT(x, y);
  157. #  else
  158.     tmp1 = isok(x,y) && !IS_ROCK(levl[x][y].typ) && !MON_AT(x, y);
  159. #  endif
  160.     tmp2 = !sobj_at(BOULDER,x,y) && !t_at(x,y);
  161.     tmp3 = !(is_pool(x,y) &&
  162.            !(Levitation || Wwalking
  163. #ifdef POLYSELF
  164.          || is_flyer(uasmon)
  165. #endif
  166.         )) && !closed_door(x,y);
  167.     return(tmp1 && tmp2 && tmp3);
  168. #else
  169.     return( isok(x,y) &&
  170. #  ifdef POLYSELF
  171.         (!IS_ROCK(levl[x][y].typ) || passes_walls(uasmon)) &&
  172. #  else
  173.         !IS_ROCK(levl[x][y].typ) &&
  174. #  endif
  175.         !MON_AT(x, y) &&
  176.         !sobj_at(BOULDER,x,y) && !t_at(x,y) &&
  177.         !(is_pool(x,y) &&
  178.         !(Levitation || Wwalking
  179. #ifdef POLYSELF
  180.           || is_flyer(uasmon)
  181. #endif
  182.           )) && !closed_door(x,y));
  183. #endif
  184.     /* Note: gold is permitted (because of vaults) */
  185. }
  186.  
  187. static void
  188. vtele() {
  189.     register struct mkroom *croom;
  190.  
  191.     for(croom = &rooms[0]; croom->hx >= 0; croom++)
  192.         if(croom->rtype == VAULT) {
  193.         register int x, y;
  194.  
  195.         x = rn2(2) ? croom->lx : croom->hx;
  196.         y = rn2(2) ? croom->ly : croom->hy;
  197.         if(teleok(x,y)) {
  198.             teleds(x,y);
  199.             return;
  200.         }
  201.         }
  202.     tele();
  203. }
  204.  
  205. void
  206. fall_through(td)
  207. boolean td;    /* td == TRUE : trapdoor */
  208. {
  209.     register int newlevel = dlevel + 1;
  210.  
  211.     while(!rn2(4) && newlevel < 29) newlevel++;
  212.     if(td) pline("A trap door opens up under you!");
  213.     else pline("The floor opens up under you!");
  214.     if(Levitation || u.ustuck || dlevel == MAXLEVEL
  215. #ifdef POLYSELF
  216.         || is_flyer(uasmon) || u.umonnum == PM_WUMPUS
  217. #endif
  218. #ifdef ENDGAME
  219.         || dlevel == ENDLEVEL
  220. #endif
  221.     ) {
  222.         You("don't fall in.");
  223.         if(!td) {
  224.         more();
  225.         pline("The opening under you closes up.");
  226.         }
  227.         return;
  228.     }
  229. #ifdef WALKIES
  230.     if(!next_to_u()) {
  231.         You("are jerked back by your pet!");
  232.         if(!td) {
  233.         more();
  234.         pline("The opening in the floor closes up.");
  235.         }
  236.     } else {
  237. #endif
  238.         if(in_shop(u.ux, u.uy)) shopdig(1);
  239.         unsee();
  240.         (void) fflush(stdout);
  241.         goto_level(newlevel, FALSE, TRUE);
  242.         if(!td) pline("The hole in the ceiling above you closes up.");
  243. #ifdef WALKIES
  244.     }
  245. #endif
  246. }
  247.  
  248. void
  249. dotrap(trap)
  250. register struct trap *trap;
  251. {
  252.     register int ttype = trap->ttyp;
  253.     register struct monst *mtmp;
  254.     register struct obj *otmp;
  255.  
  256.     nomul(0);
  257.     if(trap->tseen && !Fumbling && !(ttype == PIT
  258.        || ttype == SPIKED_PIT
  259. #ifdef SPELLS
  260.        || ttype == ANTI_MAGIC
  261. #endif
  262.         ) && !rn2(5))
  263.         You("escape a%s.", traps[ttype]);
  264.     else {
  265.         trap->tseen = 1;
  266.         if(Invisible && ttype != MONST_TRAP)
  267.         newsym(trap->tx,trap->ty);
  268.         switch(ttype) {
  269.         case SLP_GAS_TRAP:
  270.             if(Sleep_resistance) {
  271.             You("are enveloped in a cloud of gas!");
  272.             break;
  273.             }
  274.             pline("A cloud of gas puts you to sleep!");
  275.             flags.soundok = 0;
  276.             nomul(-rnd(25));
  277.             afternmv = Hear_again;
  278.             break;
  279.         case BEAR_TRAP:
  280.             if(Levitation
  281. #ifdef POLYSELF
  282.                 || is_flyer(uasmon)) {
  283.             You("%s over a bear trap.",
  284.                   Levitation ? "float" : "fly");
  285. #else
  286.                 ) {
  287.             You("float over a bear trap.");
  288. #endif
  289.             break;
  290.             }
  291. #ifdef POLYSELF
  292.             if(amorphous(uasmon)) {
  293.             pline("A bear trap closes harmlessly through you.");
  294.             break;
  295.             }
  296. #endif
  297.             u.utrap = 4 + rn2(4);
  298.             u.utraptype = TT_BEARTRAP;
  299.             pline("A bear trap closes on your %s!",
  300.             body_part(FOOT));
  301. #ifdef POLYSELF
  302.             if(u.umonnum == PM_OWLBEAR || u.umonnum == PM_BUGBEAR)
  303.             You("howl in anger!");
  304. #endif
  305.             break;
  306.         case STATUE_TRAP:
  307.             deltrap(trap);
  308.             for(otmp=level.objects[u.ux][u.uy];
  309.                         otmp; otmp = otmp->nexthere)
  310.             if(otmp->otyp == STATUE && otmp->corpsenm == trap->pm)
  311.                 if(mtmp=makemon(&mons[trap->pm],u.ux,u.uy)) {
  312.                 pline("The statue comes to life!");
  313.                 delobj(otmp);
  314.                 break;
  315.                 }
  316.             break;
  317.         case MONST_TRAP:
  318.             if(mtmp=makemon(&mons[trap->pm],u.ux,u.uy)) {
  319.               mtmp->mpeaceful = FALSE;
  320.               switch(mtmp->data->mlet) {
  321.             case S_PIERCER:
  322.                 pline("%s suddenly drops from the ceiling!",
  323.                   Xmonnam(mtmp));
  324.                 if(uarmh)
  325.                 pline("Its blow glances off your helmet.");
  326.                 else
  327.                 (void) thitu(3,d(4,6),(struct obj *)0,
  328.                     "falling piercer");
  329.                 break;
  330.             default:    /* monster surprises you. */
  331.                 pline("%s attacks you by surprise!",
  332.                   Xmonnam(mtmp));
  333.                 break;
  334.               }
  335.             }
  336.             deltrap(trap);
  337.             break;
  338.         case ARROW_TRAP:
  339.             pline("An arrow shoots out at you!");
  340.             if(!thitu(8,rnd(6),(struct obj *)0,"arrow")){
  341.             (void) mksobj_at(ARROW, u.ux, u.uy);
  342.             fobj->quan = 1;
  343.             fobj->owt = weight(fobj);
  344.             }
  345.             break;
  346.         case TRAPDOOR:
  347.             if(is_maze_lev
  348. #ifdef STRONGHOLD
  349.              && (dlevel > stronghold_level)
  350. #endif
  351.               ) {
  352.     pline("A trap door in the ceiling opens and a rock falls on your %s!",
  353.                 body_part(HEAD));
  354.             if(uarmh)
  355.                 pline("Fortunately, you are wearing a helmet!");
  356.             losehp(uarmh ? 2 : d(2,10),"falling rock", KILLED_BY_AN);
  357.             (void) mksobj_at(ROCK, u.ux, u.uy);
  358.             fobj->quan = 1;
  359.             fobj->owt = weight(fobj);
  360.             stackobj(fobj);
  361.             if(Invisible
  362. #ifdef POLYSELF
  363.                 || u.uundetected
  364. #endif
  365.                         ) newsym(u.ux, u.uy);
  366.             } else fall_through(TRUE);
  367.             break;
  368.         case DART_TRAP:
  369.             pline("A little dart shoots out at you!");
  370.             if(thitu(7,rnd(3),(struct obj *)0,"little dart")) {
  371.             if(!rn2(6)) poisoned("dart",A_CON,"poison dart",10);
  372.             } else {
  373.             (void) mksobj_at(DART, u.ux, u.uy);
  374.             fobj->quan = 1;
  375.             if(!rn2(6)) fobj->opoisoned = 1;
  376.             fobj->owt = weight(fobj);
  377.             }
  378.             break;
  379.         case TELEP_TRAP:
  380.             if(trap->once) {
  381. #ifdef ENDGAME
  382.             if(dlevel == ENDLEVEL) {
  383.                 You("feel a wrenching sensation.");
  384.                 break;
  385.             }
  386. #endif
  387.             if(Antimagic) {
  388.                 shieldeff(u.ux, u.uy);
  389.                 You("feel a wrenching sensation.");
  390.             } else {
  391.                 deltrap(trap);
  392.                 newsym(u.ux, u.uy);
  393.                 vtele();
  394.             }
  395.             } else {
  396. #ifdef ENDGAME
  397.             if(dlevel == ENDLEVEL) {
  398.                 You("feel a wrenching sensation.");
  399.                 break;
  400.             }
  401. #endif
  402.             if(Antimagic) {
  403.                 shieldeff(u.ux, u.uy);
  404.                 You("feel a wrenching sensation.");
  405.             } else {
  406.                 newsym(u.ux, u.uy);
  407.                 tele();
  408.             }
  409.             }
  410.             break;
  411.         case RUST_TRAP:
  412. #ifdef POLYSELF
  413. # ifdef GOLEMS
  414.             if (u.umonnum == PM_IRON_GOLEM) {
  415.             pline("A gush of water hits you!");
  416.             You("are covered with rust!");
  417.             rehumanize();
  418.             break;
  419.             } else
  420. # endif /* GOLEMS */
  421.             if (u.umonnum == PM_GREMLIN && rn2(3)) {
  422.             pline("A gush of water hits you!");
  423.             if(mtmp = cloneu()) {
  424.                 mtmp->mhpmax = (u.mhmax /= 2);
  425.                 You("multiply.");
  426.             }
  427.             break;
  428.             }
  429. #endif
  430.         /* Unlike monsters, traps cannot aim their rust attacks at
  431.          * you, so instead of looping through and taking either the
  432.          * first rustable one or the body, we take whatever we get,
  433.          * even if it is not rustable.
  434.          */
  435.             switch (rn2(5)) {
  436.             case 0:
  437.                 pline("A gush of water hits you on the %s!",
  438.                     body_part(HEAD));
  439.                 (void) rust_dmg(uarmh, "helmet", 1, TRUE);
  440.                 break;
  441.             case 1:
  442.                 pline("A gush of water hits your left %s!",
  443.                     body_part(ARM));
  444.                 if (rust_dmg(uarms, "shield", 1, TRUE)) break;
  445.                 if (uwep && bimanual(uwep))
  446.                 goto two_hand;
  447.                 /* Two goto statements in a row--aaarrrgggh! */
  448. glovecheck:            (void) rust_dmg(uarmg, "gauntlets", 1, TRUE);
  449.                 /* Not "metal gauntlets" since it gets called
  450.                  * even if it's leather for the message
  451.                  */
  452.                 break;
  453.             case 2:
  454.                 pline("A gush of water hits your right %s!",
  455.                     body_part(ARM));
  456. two_hand:            corrode_weapon();
  457.                 goto glovecheck;
  458.             default:
  459.                 pline("A gush of water hits you!");
  460.                 if (uarmc) (void) rust_dmg(uarmc, "cloak", 1, TRUE);
  461.                 else if (uarm)
  462.                 (void) rust_dmg(uarm, "armor", 1, TRUE);
  463. #ifdef SHIRT
  464.                 else if (uarmu)
  465.                 (void) rust_dmg(uarmu, "shirt", 1, TRUE);
  466. #endif
  467.             }
  468.             break;
  469.         case PIT:
  470.             if (Levitation
  471. #ifdef POLYSELF
  472.             || is_flyer(uasmon) || u.umonnum == PM_WUMPUS
  473. #endif
  474.             ) {
  475.             pline("A pit opens up under you!");
  476.             You("don't fall in!");
  477.             break;
  478.             }
  479.             You("fall into a pit!");
  480. #ifdef POLYSELF
  481.             if (!passes_walls(uasmon))
  482. #endif
  483.             u.utrap = rn1(6,2);
  484.             u.utraptype = TT_PIT;
  485.             losehp(rnd(6),"fell into a pit", NO_KILLER_PREFIX);
  486.             selftouch("Falling, you");
  487.             break;
  488.         case SPIKED_PIT:
  489.             if (Levitation
  490. #ifdef POLYSELF
  491.             || is_flyer(uasmon) || u.umonnum == PM_WUMPUS
  492. #endif
  493.             ) {
  494.             pline("A pit full of spikes opens up under you!");
  495.             You("don't fall in!");
  496.             break;
  497.             }
  498.             You("fall into a pit!");
  499.             You("land on a set of sharp iron spikes!");
  500. #ifdef POLYSELF
  501.             if (!passes_walls(uasmon))
  502. #endif
  503.             u.utrap = rn1(6,2);
  504.             u.utraptype = TT_PIT;
  505.             losehp(rnd(10),"fell into a pit of iron spikes",
  506.             NO_KILLER_PREFIX);
  507.             if(!rn2(6)) poisoned("spikes",A_STR,"fall onto poison spikes",8);
  508.             selftouch("Falling, you");
  509.             break;
  510.         case LEVEL_TELEP:
  511.  
  512.             {    int oldl = dlevel;
  513.  
  514.             You("%s onto a level teleport trap!",
  515.               Levitation ? "float" :
  516. #ifdef POLYSELF
  517.               locomotion(uasmon, "step"));
  518. #else
  519.               "step");
  520. #endif
  521.             if(Antimagic) {
  522.             pru();
  523.             shieldeff(u.ux, u.uy);
  524.             }
  525.             if(Antimagic
  526. #ifdef ENDGAME
  527.                 || dlevel == ENDLEVEL
  528. #endif
  529.                             ) {
  530.             You("feel a wrenching sensation.");
  531.             break;
  532.             }
  533.             if(!Blind)
  534.               You("are momentarily blinded by a flash of light.");
  535.             else
  536.             You("are momentarily disoriented.");
  537.             deltrap(trap);
  538.             newsym(u.ux,u.uy);
  539.             level_tele();
  540.             if(oldl == dlevel && !Invisible
  541. #ifdef POLYSELF
  542.                         && !u.uundetected
  543. #endif
  544.                                 ) {
  545.             levl[u.ux][u.uy].seen = 0; /* force atl */
  546.             atl(u.ux,u.uy,(char)u.usym);
  547.             }
  548.         }
  549.             break;
  550. #ifdef SPELLS
  551.         case ANTI_MAGIC:
  552.             if(Antimagic) {
  553.             shieldeff(u.ux, u.uy);
  554.             You("feel momentarily lethargic.");
  555.             } else drain_en(rnd((int)u.ulevel) + 1);
  556.             break;
  557. #endif
  558. #ifdef POLYSELF
  559.         case POLY_TRAP:
  560.             if(Antimagic) {
  561.             shieldeff(u.ux, u.uy);
  562.             You("feel momentarily different.");
  563.             /* Trap did nothing; don't remove it --KAA */
  564.             } else {
  565.             You("feel a change coming over you.");
  566.             polyself();
  567.             deltrap(trap);
  568.             }
  569.             break;
  570. #endif
  571.         case MGTRP:        /* A magic trap. */
  572.             if (!rn2(30)) {
  573.             You("are caught in a magical explosion!");
  574.             losehp(rnd(10), "magical explosion", KILLED_BY_AN);
  575. #ifdef SPELLS
  576.             Your("body absorbs some of the magical energy!");
  577.             u.uen = (u.uenmax += 2);
  578. #endif
  579.             deltrap(trap);
  580.             if(Invisible
  581. #ifdef POLYSELF
  582.                 && !u.uundetected
  583. #endif
  584.                         ) newsym(u.ux,u.uy);
  585.             } else domagictrap();
  586.             break;
  587.         case SQBRD:        /* stepped on a squeaky board */
  588.             if (Levitation
  589. #ifdef POLYSELF
  590.             || is_flyer(uasmon)
  591. #endif
  592.             ) {
  593.             if (Hallucination) You("notice a crease in the linoleum.");
  594.             else You("notice a loose board below you.");
  595.             } else {
  596.             pline("A board beneath you squeaks loudly.");
  597.             wake_nearby();
  598.             }
  599.             break;
  600.         case WEB: /* Our luckless player has stumbled into a web. */
  601.  
  602.             You("%s into a spider web!",
  603.               Levitation ? "float" :
  604. #ifdef POLYSELF
  605.               locomotion(uasmon, "stumble"));
  606. #else
  607.               "stumble");
  608. #endif
  609.             u.utraptype = TT_WEB;
  610.  
  611.             /* Time stuck in the web depends on your strength. */
  612.  
  613.             if (ACURR(A_STR) == 3) u.utrap = rn1(6,6);
  614.             else if (ACURR(A_STR) < 6) u.utrap = rn1(6,4);
  615.             else if (ACURR(A_STR) < 9) u.utrap = rn1(4,4);
  616.             else if (ACURR(A_STR) < 12) u.utrap = rn1(4,2);
  617.             else if (ACURR(A_STR) < 15) u.utrap = rn1(2,2);
  618.             else if (ACURR(A_STR) < 18) u.utrap = rnd(2);
  619.             else if (ACURR(A_STR) < 69) u.utrap = 1;
  620.             else {
  621.             u.utrap = 0;
  622.             You("tear through the web!");
  623.             deltrap(trap);
  624.                if(Invisible) newsym(u.ux,u.uy);
  625.             }
  626.             break;
  627.  
  628.         case LANDMINE: {
  629. #ifndef LINT
  630.             register struct monst *mtmp = fmon;
  631. #endif
  632.  
  633.             if (Levitation
  634. #ifdef POLYSELF
  635.                     || is_flyer(uasmon)
  636. #endif
  637.                                 ) {
  638.             You("see a trigger in a pile of soil below you.");
  639.             if (rn2(3)) break;
  640.             pline("KAABLAMM!!!  The air currents set it off!");
  641.             } else {
  642.             pline("KAABLAMM!!!  You triggered a land mine!");
  643.             set_wounded_legs(LEFT_SIDE, 40 + rnd(35));
  644.             set_wounded_legs(RIGHT_SIDE, 40 + rnd(35));
  645.             }
  646.             losehp(rnd(16), "land mine", KILLED_BY_AN);
  647.             /* wake everything on the level */
  648.             while(mtmp) {
  649.             if(mtmp->msleep) mtmp->msleep = 0;
  650.             mtmp = mtmp->nmon;
  651.             }
  652.             deltrap(t_at(u.ux, u.uy)); /* mines only explode once */
  653.             if(Invisible) newsym(u.ux,u.uy);
  654.             }
  655.             break;
  656.         default:
  657.             impossible("You hit a trap of type %u", trap->ttyp);
  658.         }
  659.     }
  660. }
  661.  
  662. #endif /* OVLB */
  663.  
  664. #ifdef WALKIES
  665.  
  666. STATIC_DCL boolean FDECL(teleport_pet, (struct monst *));
  667.  
  668. #ifdef OVLB
  669.  
  670. STATIC_OVL boolean
  671. teleport_pet(mtmp)
  672. register struct monst *mtmp;
  673. {
  674.     register struct obj *otmp;
  675.  
  676.     if(mtmp->mleashed) {
  677.         otmp = get_mleash(mtmp);
  678.         if(!otmp)
  679.         impossible("%s is leashed, without a leash.", Monnam(mtmp));
  680.         if(otmp->cursed) {
  681. # ifdef SOUNDS
  682.         yelp(mtmp);
  683. # endif
  684.         return FALSE;
  685.         } else {
  686.         Your("leash goes slack.");
  687.         m_unleash(mtmp);
  688.         return TRUE;
  689.         }
  690.     }
  691.     return TRUE;
  692. }
  693.  
  694. #endif /* OVLB */
  695.  
  696. #endif /* WALKIES */
  697.  
  698. STATIC_DCL void FDECL(seetrap, (struct trap *));
  699.  
  700. #ifdef OVLB
  701.  
  702. STATIC_OVL void
  703. seetrap(trap)
  704.  
  705.     register struct trap *trap;
  706. {
  707.     if(!trap->tseen) {
  708.  
  709.         trap->tseen = 1;
  710.         newsym(trap->tx, trap->ty);
  711.     }
  712. }
  713.  
  714. #endif /* OVLB */
  715. #ifdef OVL1
  716.  
  717. int
  718. mintrap(mtmp)
  719. register struct monst *mtmp;
  720. {
  721.     register struct trap *trap = t_at(mtmp->mx, mtmp->my);
  722.     register int newlev, wasintrap = mtmp->mtrapped;
  723.     register boolean trapkilled = FALSE, tdoor = FALSE;
  724.     struct obj *otmp;
  725.  
  726.     if(!trap) {
  727.         mtmp->mtrapped = 0;    /* perhaps teleported? */
  728.     } else if(wasintrap) {
  729.         if(!rn2(40)) mtmp->mtrapped = 0;
  730.     } else {
  731.         register int tt = trap->ttyp;
  732.  
  733.     /* A bug fix for dumb messages by ab@unido.
  734.      */
  735.         int in_sight = cansee(mtmp->mx,mtmp->my)
  736.                && (!mtmp->minvis || See_invisible);
  737.  
  738.         if(mtmp->mtrapseen & (1 << tt)) {
  739.         /* he has been in such a trap - perhaps he escapes */
  740.         if(rn2(4)) return(0);
  741.         }
  742.         mtmp->mtrapseen |= (1 << tt);
  743.         switch (tt) {
  744.         case BEAR_TRAP:
  745.             if(mtmp->data->msize > MZ_SMALL &&
  746.                !amorphous(mtmp->data)) {
  747.                 mtmp->mtrapped = 1;
  748.                 if(in_sight) {
  749.                   pline("%s is caught in a bear trap!",
  750.                     Monnam(mtmp));
  751.                   seetrap(trap);
  752.                 } else
  753.                     if((mtmp->data == &mons[PM_OWLBEAR]
  754.                     || mtmp->data == &mons[PM_BUGBEAR])
  755.                     && flags.soundok)
  756.                 You("hear the roaring of an angry bear!");
  757.             }
  758.             break;
  759. #ifdef POLYSELF
  760.         case POLY_TRAP:
  761.             if(!resist(mtmp, WAND_SYM, 0, NOTELL)) {
  762.             (void) newcham(mtmp, (struct permonst *)0);
  763.             seetrap(trap);
  764.             }
  765.             break;
  766. #endif
  767.         case RUST_TRAP:
  768.             if(in_sight)
  769.                 pline("A gush of water hits %s!", mon_nam(mtmp));
  770.             if(cansee(mtmp->mx,mtmp->my))
  771.                 seetrap(trap);
  772. #ifdef GOLEMS
  773.             if (mtmp->data == &mons[PM_IRON_GOLEM]) {
  774.                 if (in_sight)
  775.                     pline("%s falls to pieces!", Monnam(mtmp));
  776.                 else if(mtmp->mtame)
  777.                     pline("May %s rust in peace.",
  778.                                 mon_nam(mtmp));
  779.                 mondied(mtmp);
  780.                 trapkilled = TRUE;
  781.             } else
  782. #endif /* GOLEMS */
  783.             if (mtmp->data == &mons[PM_GREMLIN] && rn2(3)) {
  784.                 struct monst *mtmp2 = clone_mon(mtmp);
  785.  
  786.                 if (mtmp2) {
  787.                     mtmp2->mhpmax = (mtmp->mhpmax /= 2);
  788.                     if(in_sight)
  789.                     pline("%s multiplies.", Monnam(mtmp));
  790.                 }
  791.             }
  792.             break;
  793.         case PIT:
  794.         case SPIKED_PIT:
  795.             /* TO DO: there should be a mtmp/data -> floating */
  796.             if(!is_flyer(mtmp->data) &&
  797.                mtmp->data != &mons[PM_WUMPUS]) {
  798.                 if (!passes_walls(mtmp->data))
  799.                     mtmp->mtrapped = 1;
  800.                 if(in_sight) {
  801.                     pline("%s falls into a pit!", Monnam(mtmp));
  802.                     seetrap(trap);
  803.                 }
  804.                 if(thitm(0, mtmp, (struct obj *)0,
  805.                      rnd((tt==PIT) ? 6 : 10)))
  806.                     trapkilled = TRUE;
  807.             }
  808.             break;
  809.         case SLP_GAS_TRAP:
  810.             if(!resists_sleep(mtmp->data) &&
  811.                !mtmp->msleep && mtmp->mcanmove) {
  812.                 mtmp->mcanmove = 0;
  813.                 mtmp->mfrozen = rnd(25);
  814.                 if(in_sight)
  815.                   pline("%s suddenly falls asleep!",
  816.                     Monnam(mtmp));
  817.                 if(cansee(mtmp->mx,mtmp->my))
  818.                     seetrap(trap);
  819.             }
  820.             break;
  821.         case TELEP_TRAP:
  822. #ifdef WALKIES
  823.             if(teleport_pet(mtmp)) {
  824. #endif
  825.                 /* Note: don't remove the trap if a vault.  Other-
  826.                  * the monster will be stuck there, since the guard
  827.                  * isn't going to come for it...
  828.                  */
  829.                 if (trap->once) vloc(mtmp);
  830.                 else rloc(mtmp);
  831.                 if(in_sight && !cansee(mtmp->mx,mtmp->my)) {
  832.                 pline("%s suddenly disappears!",
  833.                     Monnam(mtmp));
  834.                 seetrap(trap);
  835.                 }
  836. #ifdef WALKIES
  837.             }
  838. #endif
  839.             break;
  840.         case ARROW_TRAP:
  841.             otmp = mksobj(ARROW, FALSE);
  842.             otmp->quan = 1;
  843.             otmp->owt = weight(otmp);
  844.             if(in_sight) seetrap(trap);
  845.             if(thitm(8, mtmp, otmp, 0)) trapkilled = TRUE;
  846.             break;
  847.         case DART_TRAP:
  848.             otmp = mksobj(DART, FALSE);
  849.             otmp->quan = 1;
  850.             if (!rn2(6)) otmp->opoisoned = 1;
  851.             otmp->owt = weight(otmp);
  852.             if(in_sight) seetrap(trap);
  853.             if(thitm(7, mtmp, otmp, 0)) trapkilled = TRUE;
  854.             break;
  855.         case TRAPDOOR:
  856.             if(is_maze_lev
  857. #ifdef STRONGHOLD
  858.                && (dlevel > stronghold_level && dlevel < MAXLEVEL)
  859. #endif
  860.               ) {
  861.                 otmp = mksobj(ROCK, FALSE);
  862.                 otmp->quan = 1;
  863.                 otmp->owt = weight(otmp);
  864.                 if(in_sight) seetrap(trap);
  865.                 if(thitm(0, mtmp, otmp, d(2, 10)))
  866.                     trapkilled = TRUE;
  867.                 break;
  868.             }
  869.             if (mtmp->data == &mons[PM_WUMPUS]) break;
  870.             tdoor = TRUE;
  871.             /* Fall through */
  872.         case LEVEL_TELEP:
  873.             if(!is_flyer(mtmp->data)
  874. #ifdef WORM
  875.                 && !mtmp->wormno
  876.                 /* long worms with tails mustn't change levels */
  877. #endif
  878.                 ) {
  879. #ifdef WALKIES
  880.                 if(teleport_pet(mtmp)) {
  881. #endif
  882.                 if(tdoor)
  883.                     fall_down(mtmp, dlevel+1);
  884.                 else {
  885.                     newlev = rnd(3);
  886.                     if(!rn2(2)) newlev = -(newlev);
  887.                     newlev = dlevel + newlev;
  888.                     if(newlev > MAXLEVEL) {
  889.                     if(dlevel != MAXLEVEL)
  890.                         newlev = MAXLEVEL;
  891.                     else newlev = MAXLEVEL - rnd(3);
  892.                     }
  893.                     if(newlev < 1) {
  894.                     if(dlevel != 1) newlev = 1;
  895.                     else newlev = 1 + rnd(3);
  896.                     }
  897.                     fall_down(mtmp, newlev);
  898.                 }
  899.                 if(in_sight) {
  900.         pline("Suddenly, %s disappears out of sight.", mon_nam(mtmp));
  901.                     seetrap(trap);
  902.                 }
  903.                 return(2);    /* no longer on this level */
  904. #ifdef WALKIES
  905.                 }
  906. #endif
  907.             }
  908.             break;
  909.         case MONST_TRAP:
  910.         case STATUE_TRAP:
  911.             break;
  912.         case MGTRP:
  913.             /* A magic trap.  Monsters immune. */
  914.             break;
  915.         case SQBRD: {
  916.             register struct monst *ztmp = fmon;
  917.  
  918.             if(is_flyer(mtmp->data)) break;
  919.             /* stepped on a squeaky board */
  920.             if (in_sight) {
  921.                 pline("A board beneath %s squeaks loudly.", mon_nam(mtmp));
  922.                 seetrap(trap);
  923.             } else
  924.                You("hear a distant squeak.");
  925.             /* wake up nearby monsters */
  926.             while(ztmp) {
  927.                 if(dist2(mtmp->mx,mtmp->my,ztmp->mx,ztmp->my) < 40)
  928.                 if(ztmp->msleep) ztmp->msleep = 0;
  929.                 ztmp = ztmp->nmon;
  930.             }
  931.             break;
  932.         }
  933.            case WEB:
  934.             /* Monster in a web. */
  935.             if(mtmp->data->mlet != S_SPIDER) {
  936.                 if(in_sight)
  937.                 pline("%s is caught in a web.", Monnam(mtmp));
  938.                 else /* Eric Backus */
  939.                 if(mtmp->data == &mons[PM_OWLBEAR] ||
  940.                     mtmp->data == &mons[PM_BUGBEAR])
  941.                     You("hear the roaring of a confused bear!");
  942.                 mtmp->mtrapped = 1;
  943.             }
  944.             break;
  945. #ifdef SPELLS
  946.         case ANTI_MAGIC:    break;
  947. #endif
  948.         case LANDMINE: {
  949.             register struct monst *mntmp = fmon;
  950.  
  951.             if(rn2(3))
  952.                 break; /* monsters usually don't set it off */
  953.             if(is_flyer(mtmp->data)) {
  954.                 if (in_sight) {
  955.     pline("A trigger appears in a pile of soil below %s.", Monnam(mtmp));
  956.                     seetrap(trap);
  957.                 }
  958.                 if (rn2(3)) break;
  959.                 if (in_sight)
  960.                     pline("The air currents set it off!");
  961.             } else if(in_sight)
  962.                 pline("KAABLAMM!!!  %s triggers a land mine!",
  963.                   Monnam(mtmp));
  964.             if (!in_sight && flags.soundok)
  965.                 pline("Kaablamm!  You hear an explosion in the distance!");
  966.             deltrap(t_at(mtmp->mx, mtmp->my));
  967.             if(thitm(0, mtmp, (struct obj *)0, rnd(16)))
  968.                 trapkilled = TRUE;
  969.             /* wake everything on the level */
  970.             while(mntmp) {
  971.                 if(mntmp->msleep)
  972.                     mntmp->msleep = 0;
  973.                 mntmp = mntmp->nmon;
  974.             }
  975.             break;
  976.         }
  977.         default:
  978.             impossible("Some monster encountered a strange trap of type %d.", tt);
  979.         }
  980.     }
  981.     if(trapkilled) return 2;
  982.     else return mtmp->mtrapped;
  983. }
  984.  
  985. #endif /* OVL1 */
  986. #ifdef OVLB
  987.  
  988. void
  989. selftouch(arg)
  990. const char *arg;
  991. {
  992.     if(uwep && (uwep->otyp == CORPSE && uwep->corpsenm == PM_COCKATRICE)
  993. #ifdef POLYSELF
  994.             && !resists_ston(uasmon)
  995. #endif
  996.     ){
  997.         pline("%s touch the cockatrice corpse.", arg);
  998.         You("turn to stone...");
  999.         killer_format = KILLED_BY;
  1000.         killer = "touching a cockatrice corpse";
  1001.         done(STONING);
  1002.     }
  1003. }
  1004.  
  1005. void
  1006. float_up() {
  1007.     if(u.utrap) {
  1008.         if(u.utraptype == TT_PIT) {
  1009.             u.utrap = 0;
  1010.             You("float up, out of the pit!");
  1011.         } else {
  1012.             You("float up, only your %s is still stuck.",
  1013.                 body_part(LEG));
  1014.         }
  1015.     } else
  1016.         if (Hallucination)
  1017.             pline("Up, up, and awaaaay!  You're walking on air!");
  1018.         else
  1019.             You("start to float in the air!");
  1020. }
  1021.  
  1022. int
  1023. float_down() {
  1024.     register struct trap *trap;
  1025.  
  1026.     if(Levitation) return(0); /* maybe another ring/potion/boots */
  1027.  
  1028.     /* check for falling into pool - added by GAN 10/20/86 */
  1029.     if(is_pool(u.ux,u.uy) && !(Wwalking
  1030. #ifdef POLYSELF
  1031.                     || is_flyer(uasmon)
  1032. #endif
  1033.                     ))
  1034.         drown();
  1035.  
  1036.     You("float gently to the ground.");
  1037.     if(trap = t_at(u.ux,u.uy))
  1038.         switch(trap->ttyp) {
  1039.         case MONST_TRAP:
  1040.         case STATUE_TRAP:
  1041.             break;
  1042.         case TRAPDOOR:
  1043.             if(is_maze_lev
  1044. #ifdef STRONGHOLD
  1045.                && (dlevel >= stronghold_level || dlevel < MAXLEVEL)
  1046. #endif
  1047.                || u.ustuck) break;
  1048.             /* fall into next case */
  1049.         default:
  1050.             dotrap(trap);
  1051.     }
  1052.     if(!flags.nopick && (OBJ_AT(u.ux, u.uy) || levl[u.ux][u.uy].gmask))
  1053.         pickup(1);
  1054.     return 0;
  1055. }
  1056.  
  1057.  
  1058. void
  1059. tele() {
  1060.     coord cc;
  1061.     register int nux,nuy;
  1062.  
  1063. #ifdef STRONGHOLD
  1064.     /* Disable teleportation in stronghold && Vlad's Tower */
  1065.     if(dlevel == stronghold_level ||
  1066. # ifdef ENDGAME
  1067.        dlevel == ENDLEVEL ||
  1068. # endif
  1069.        (dlevel >= tower_level && dlevel <= tower_level + 2)) {
  1070. # ifdef WIZARD
  1071.         if (!wizard) {
  1072. # endif
  1073.             pline("A mysterious force prevents you from teleporting!");
  1074.             return;
  1075. # ifdef WIZARD
  1076.         }
  1077. # endif
  1078.     }
  1079. #endif /* STRONGHOLD /**/
  1080.     if((u.uhave_amulet || dlevel == wiz_level) && !rn2(3)) {
  1081.         You("feel disoriented for a moment.");
  1082.         return;
  1083.     }
  1084.     if(Teleport_control) {
  1085.         if (unconscious())
  1086.         pline("Being unconscious, you cannot control your teleport.");
  1087.         else {
  1088.             pline("To what position do you want to be teleported?");
  1089.             cc.x = u.ux;
  1090.             cc.y = u.uy;
  1091.             getpos(&cc, 1, "the desired position"); /* 1: force valid */
  1092.             /* possible extensions: introduce a small error if
  1093.                magic power is low; allow transfer to solid rock */
  1094.             if(teleok(cc.x, cc.y)){
  1095.             teleds(cc.x, cc.y);
  1096.             return;
  1097.             }
  1098.             pline("Sorry...");
  1099.         }
  1100.     }
  1101.     do {
  1102.         nux = rnd(COLNO-1);
  1103.         nuy = rn2(ROWNO);
  1104.     } while(!teleok(nux, nuy));
  1105.     teleds(nux, nuy);
  1106. }
  1107.  
  1108. void
  1109. teleds(nux, nuy)
  1110. register int nux,nuy;
  1111. {
  1112.     if(Punished) unplacebc();
  1113.     unsee();
  1114.     u.utrap = 0;
  1115.     u.ustuck = 0;
  1116.     u.ux0 = u.ux;
  1117.     u.uy0 = u.uy;
  1118.     u.ux = nux;
  1119.     u.uy = nuy;
  1120. #ifdef POLYSELF
  1121.     if (hides_under(uasmon))
  1122.         u.uundetected = (OBJ_AT(nux, nuy) || levl[nux][nuy].gmask);
  1123.     else 
  1124.         u.uundetected = 0;
  1125.     if (u.usym == S_MIMIC_DEF) u.usym = S_MIMIC;
  1126. #endif
  1127.     if(Punished) placebc(1);
  1128.     if(u.uswallow){
  1129.         u.uswldtim = u.uswallow = 0;
  1130.         docrt();
  1131.     }
  1132.     setsee();
  1133.     nomul(0);
  1134.     spoteffects();
  1135. }
  1136.  
  1137. int
  1138. dotele()
  1139. {
  1140.     struct trap *trap;
  1141. #ifdef SPELLS
  1142.     boolean castit = FALSE;
  1143. # ifdef __GNULINT__
  1144.     register int sp_no = 0;
  1145. # else
  1146.     register int sp_no;
  1147. # endif
  1148. #endif
  1149.  
  1150.     trap = t_at(u.ux, u.uy);
  1151.     if (trap && (!trap->tseen || trap->ttyp != TELEP_TRAP))
  1152.         trap = 0;
  1153.  
  1154.     if (trap) {
  1155.         if (trap->once) {
  1156.             pline("This is a vault teleport, usable once only.");
  1157.             pline("Jump in? ");
  1158.             if (yn() == 'n')
  1159.                 trap = 0;
  1160.             else {
  1161.                 deltrap(trap);
  1162.                 newsym(u.ux, u.uy);
  1163.             }
  1164.         }
  1165.         if (trap)
  1166. #ifdef POLYSELF
  1167.             You("%s onto the teleportation trap.",
  1168.                 locomotion(uasmon, "jump"));
  1169. #else
  1170.             You("jump onto the teleportation trap.");
  1171. #endif
  1172.     }
  1173.     if(!trap && (!Teleportation ||
  1174.        (u.ulevel < (pl_character[0] == 'W' ? 8 : 12)
  1175. #ifdef POLYSELF
  1176.         && !can_teleport(uasmon)
  1177. #endif
  1178.        )
  1179.       )) {
  1180. #ifdef SPELLS
  1181.         /* Try to use teleport away spell. */
  1182.         castit = objects[SPE_TELEPORT_AWAY].oc_name_known;
  1183.         if (castit) {
  1184.             for (sp_no = 0; sp_no < MAXSPELL &&
  1185.                 spl_book[sp_no].sp_id != NO_SPELL &&
  1186.                 spl_book[sp_no].sp_id != SPE_TELEPORT_AWAY; sp_no++);
  1187.  
  1188.             if (sp_no == MAXSPELL ||
  1189.             spl_book[sp_no].sp_id != SPE_TELEPORT_AWAY)
  1190.                 castit = FALSE;
  1191.         }
  1192. #endif
  1193. #ifdef WIZARD
  1194.         if (!wizard) {
  1195. #endif
  1196. #ifdef SPELLS
  1197.             if (!castit) {
  1198.             if (!Teleportation)
  1199.                 You("don't know that spell.");
  1200.             else
  1201. #endif
  1202.                 You("are not able to teleport at will.");
  1203.             return(0);
  1204. #ifdef SPELLS
  1205.             }
  1206. #endif
  1207. #ifdef WIZARD
  1208.         }
  1209. #endif
  1210.     }
  1211.  
  1212.     if(!trap && (u.uhunger <= 100 || ACURR(A_STR) < 6)) {
  1213.         You("lack the strength for a teleport spell.");
  1214. #ifdef WIZARD
  1215.         if(!wizard)
  1216. #endif
  1217.         return(1);
  1218.     }
  1219.  
  1220. #ifdef SPELLS
  1221.     if (castit)
  1222. # ifdef WIZARD
  1223.         if (!spelleffects(++sp_no, TRUE) && !wizard) return(0);
  1224. # else
  1225.         return spelleffects(++sp_no, TRUE);
  1226. # endif
  1227. #endif
  1228.  
  1229. #ifdef WALKIES
  1230.     if(next_to_u()) {
  1231. #endif
  1232.         if (trap && trap->once) vtele();
  1233.         else tele();
  1234. #ifdef WALKIES
  1235.         (void) next_to_u();
  1236.     } else {
  1237.         You("shudder for a moment.");
  1238.         return(0);
  1239.     }
  1240. #endif
  1241.     if (!trap) morehungry(100);
  1242.     return(1);
  1243. }
  1244.  
  1245. void
  1246. placebc(attach)
  1247. int attach;
  1248. {
  1249.     if(!uchain || !uball){
  1250.         impossible("Where are your ball and chain?");
  1251.         return;
  1252.     }
  1253.     if(!carried(uball))
  1254.         place_object(uball, u.ux, u.uy);
  1255.     place_object(uchain, u.ux, u.uy);
  1256.     if(attach){
  1257.         uchain->nobj = fobj;
  1258.         fobj = uchain;
  1259.         if(!carried(uball)){
  1260.             uball->nobj = fobj;
  1261.             fobj = uball;
  1262.         }
  1263.     }
  1264. }
  1265.  
  1266. void
  1267. unplacebc(){
  1268.     if(!carried(uball)){
  1269.         freeobj(uball);
  1270.         unpobj(uball);
  1271.     }
  1272.     freeobj(uchain);
  1273.     unpobj(uchain);
  1274. }
  1275.  
  1276. void
  1277. level_tele() {
  1278.     register int newlevel;
  1279.  
  1280.     if(u.uhave_amulet
  1281. #ifdef ENDGAME
  1282.         || dlevel == ENDLEVEL
  1283. #endif
  1284.     ) {
  1285.         You("feel very disoriented for a moment.");
  1286.         return;
  1287.     }
  1288.     if(Teleport_control
  1289. #ifdef WIZARD
  1290.        || wizard
  1291. #endif
  1292.         ) {
  1293.         char buf[BUFSZ];
  1294.  
  1295.         do {
  1296.           pline("To what level do you want to teleport? [type a number] ");
  1297.           getlin(buf);
  1298.         } while(!digit(buf[0]) && (buf[0] != '-' || !digit(buf[1])));
  1299.         newlevel = atoi(buf);
  1300.     } else {
  1301. #ifdef STRONGHOLD
  1302.         /* We cannot send them to Hell if STRONGHOLD is defined, since
  1303.          * they may find themselves trapped on the other side of the
  1304.          * stronghold...
  1305.          */
  1306.         newlevel = rn2(5) ? rnd(dlevel + 3) : rnd(stronghold_level);
  1307. #else
  1308.         newlevel = rn2(5) || !Fire_resistance ? rnd(dlevel + 3) : HELLLEVEL;
  1309. #endif
  1310.         if(dlevel == newlevel)
  1311.         if(is_maze_lev) newlevel--; else newlevel++;
  1312.     }
  1313.  
  1314. #ifdef WALKIES
  1315.     if(!next_to_u()) {
  1316.         You("shudder for a moment...");
  1317.         return;
  1318.     }
  1319. #endif
  1320.  
  1321.     if(newlevel < 0) {
  1322.         if(newlevel <= -10) {
  1323.             You("arrive in heaven.");
  1324.             verbalize("Thou art early, but we'll admit thee.");
  1325.             killer_format = NO_KILLER_PREFIX;
  1326.             killer = "went to heaven prematurely";
  1327.             done(DIED);
  1328.             return;
  1329.         } else    if (newlevel == -9) {
  1330.             You("feel deliriously happy. ");
  1331.             pline("(In fact, you're on Cloud 9!) ");
  1332.             more();
  1333.         } else
  1334.             You("are now high above the clouds...");
  1335.  
  1336.         if(Levitation) {
  1337.             You("float gently down to earth.");
  1338. #ifdef STRONGHOLD
  1339.             newlevel = 1;
  1340. #else
  1341.             done(ESCAPED);
  1342. #endif
  1343.         }
  1344. #ifdef POLYSELF
  1345.         else if(is_flyer(uasmon)) {
  1346.             You("fly down to earth.");
  1347. # ifdef STRONGHOLD
  1348.             newlevel = 1;
  1349. # else
  1350.             done(ESCAPED);
  1351. # endif
  1352.         }
  1353. #endif
  1354.         else {
  1355.             int save_dlevel;
  1356.  
  1357.             save_dlevel = dlevel;
  1358.             pline("Unfortunately, you don't know how to fly.");
  1359.             You("plummet a few thousand feet to your death.");
  1360.             dlevel = 0;
  1361.             killer_format = NO_KILLER_PREFIX;
  1362.             killer =
  1363.     self_pronoun("teleported out of the dungeon and fell to %s death","his");
  1364.             done(DIED);
  1365.             dlevel = save_dlevel;
  1366.             return;  
  1367.         }
  1368.     }
  1369.  
  1370.     /* calls done(ESCAPED) if newlevel==0 */
  1371.     goto_level(newlevel, FALSE, FALSE);
  1372. }
  1373.  
  1374. void
  1375. domagictrap() {
  1376.     register int fate = rnd(20);
  1377.  
  1378.     /* What happened to the poor sucker? */
  1379.  
  1380.     if (fate < 10) {
  1381.  
  1382.       /* Most of the time, it creates some monsters. */
  1383.       register int cnt = rnd(4);
  1384.  
  1385.       /* below checks for blindness added by GAN 10/30/86 */
  1386.       if (!Blind)  {
  1387.         You("are momentarily blinded by a flash of light!");
  1388.         make_blinded((long)rn1(5,10),FALSE);
  1389.       }  else
  1390.         You("hear a deafening roar!");
  1391.       while(cnt--)
  1392.         (void) makemon((struct permonst *) 0, u.ux, u.uy);
  1393.     }
  1394.     else
  1395.       switch (fate) {
  1396.  
  1397.          case 10:
  1398.          case 11:
  1399.               /* sometimes nothing happens */
  1400.             break;
  1401.          case 12:
  1402.               /* a flash of fire */
  1403.               {
  1404.             register int num;
  1405.  
  1406.             /* changed to be in conformance with
  1407.              * SCR_FIRE by GAN 11/02/86
  1408.              */
  1409.  
  1410.             pline("A tower of flame bursts from the floor!");
  1411.             if(Fire_resistance) {
  1412.                 shieldeff(u.ux, u.uy);
  1413.                 You("are uninjured.");
  1414.                 break;
  1415.             } else {
  1416.                 num = rnd(6);
  1417.                 u.uhpmax -= num;
  1418.                 losehp(num,"burst of flame", KILLED_BY_AN);
  1419.                 break;
  1420.             }
  1421.               }
  1422.  
  1423.          /* odd feelings */
  1424.          case 13:    pline("A shiver runs up and down your %s!",
  1425.                   body_part(SPINE));
  1426.             break;
  1427.          case 14:    You(Hallucination ?
  1428.                 "hear the moon howling at you." :
  1429.                 "hear distant howling.");
  1430.             break;
  1431.          case 15:    You("suddenly yearn for %s.",
  1432.                 Hallucination ? "Cleveland" :
  1433.                         "your distant homeland");
  1434.             break;
  1435.          case 16:   Your("pack shakes violently!");
  1436.             break;
  1437.          case 17:    You(Hallucination ?
  1438.                 "smell hamburgers." :
  1439.                 "smell charred flesh.");
  1440.             break;
  1441.  
  1442.          /* very occasionally something nice happens. */
  1443.  
  1444.          case 19:
  1445.             /* tame nearby monsters */
  1446.            {   register int i,j;
  1447.                register struct monst *mtmp;
  1448.  
  1449.                /* below pline added by GAN 10/30/86 */
  1450.                adjattrib(A_CHA,1,FALSE);
  1451.                for(i = -1; i <= 1; i++) for(j = -1; j <= 1; j++) {
  1452.                if(!isok(u.ux+i, u.uy+j)) continue;
  1453.                mtmp = m_at(u.ux+i, u.uy+j);
  1454.                if(mtmp)
  1455.                    (void) tamedog(mtmp, (struct obj *)0);
  1456.                }
  1457.                break;
  1458.            }
  1459.  
  1460.          case 20:
  1461.             /* uncurse stuff */
  1462.            {  register struct obj *obj;
  1463.  
  1464.             /* below plines added by GAN 10/30/86 */
  1465.             You(Hallucination ?
  1466.                 "feel in touch with the Universal Oneness." :
  1467.                 "feel like someone is helping you.");
  1468.             for(obj = invent; obj ; obj = obj->nobj)
  1469.                    if(obj->owornmask || obj->otyp == LOADSTONE)
  1470.                     obj->cursed = 0;
  1471.                if(Punished) unpunish();
  1472.                break;
  1473.            }
  1474.          default: break;
  1475.       }
  1476. }
  1477.  
  1478. void
  1479. drown() {
  1480.     register struct obj *obj;
  1481.  
  1482.     /* Scrolls and potions get affected by the water */
  1483.     for(obj = invent; obj; obj = obj->nobj) {
  1484.         if(obj->olet == SCROLL_SYM && rn2(12) > Luck
  1485. #ifdef MAIL
  1486.             && obj->otyp != SCR_MAIL
  1487. #endif
  1488.                                 )
  1489.             obj->otyp = SCR_BLANK_PAPER;
  1490.         if(obj->olet == POTION_SYM && rn2(12) > Luck) {
  1491.             if (obj->spe == -1) {
  1492.                 obj->otyp = POT_WATER;
  1493.                 obj->blessed = obj->cursed = 0;
  1494.                 obj->spe = 0;
  1495.             } else obj->spe--;
  1496.         }
  1497.     }
  1498.  
  1499. #ifdef POLYSELF
  1500.     if(u.umonnum == PM_GREMLIN && rn2(3)) {
  1501.         struct monst *mtmp;
  1502.         if(mtmp = cloneu()) {
  1503.             mtmp->mhpmax = (u.mhmax /= 2);
  1504.             You("multiply.");
  1505.         }
  1506.     }
  1507.  
  1508.     if(is_swimmer(uasmon)) return;
  1509. #endif
  1510.  
  1511.     You("fell into %s!",
  1512.           levl[u.ux][u.uy].typ == POOL ? "a pool" : "the moat");
  1513.     You("can't swim!");
  1514.     if(
  1515. #ifdef WIZARD
  1516.     wizard ||
  1517. #endif
  1518.     rn2(3) < Luck+2) {
  1519.         You("attempt a teleport spell.");    /* utcsri!carroll */
  1520.         (void) dotele();
  1521.         if(!is_pool(u.ux,u.uy)) return;
  1522.     }
  1523.     You("drown.");
  1524.     killer_format = KILLED_BY_AN;
  1525.     killer = levl[u.ux][u.uy].typ == POOL ? "pool of water" : "moat";
  1526.     done(DROWNING);
  1527. }
  1528.  
  1529. #ifdef SPELLS
  1530. void
  1531. drain_en(n)
  1532. register int n;
  1533. {
  1534.     if (!u.uenmax) return;
  1535.     You("feel your magical energy drain away!");
  1536.     u.uen -= n;
  1537.     if(u.uen < 0)  {
  1538.         u.uenmax += u.uen;
  1539.         if(u.uenmax < 0) u.uenmax = 0;
  1540.         u.uen = 0;
  1541.     }
  1542.     flags.botl = 1;
  1543. }
  1544. #endif
  1545.  
  1546. int
  1547. dountrap() {    /* disarm a trapped object */
  1548.     register struct obj *otmp;
  1549.     register boolean confused = (Confusion > 0 || Hallucination > 0);
  1550.     register int x,y;
  1551.     int ch;
  1552.     struct trap *ttmp;
  1553.  
  1554. #ifdef POLYSELF
  1555.     if(nohands(uasmon)) {
  1556.         pline("And just how do you expect to do that?");
  1557.         return(0);
  1558.     }
  1559. #endif
  1560.     if(!getdir(TRUE)) return(0);
  1561.     x = u.ux + u.dx;
  1562.     y = u.uy + u.dy;
  1563.  
  1564.     if(!u.dx && !u.dy) {
  1565.         for(otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
  1566.         if(Is_box(otmp)) {
  1567.             pline("There is %s here, check for traps? ", doname(otmp));
  1568.  
  1569.             switch (ynq()) {
  1570.             case 'q': return(0);
  1571.             case 'n': continue;
  1572.             }
  1573.  
  1574.             if((otmp->otrapped && !confused 
  1575.                 && rn2(MAXLEVEL+2-dlevel) < 10)
  1576.                || confused && !rn2(3)) {
  1577.             You("find a trap on the %s!  Disarm it? ", xname(otmp));
  1578.  
  1579.             switch (ynq()) {
  1580.                 case 'q': return(1);
  1581.                 case 'n': continue;
  1582.             }
  1583.  
  1584.             if(otmp->otrapped) {
  1585.                 ch = 15 + (pl_character[0] == 'R') ? u.ulevel*3
  1586.                                 : u.ulevel;
  1587.                 if(confused || Fumbling || rnd(75+dlevel/2) > ch) {
  1588.                 You("set it off!");
  1589.                 (void) chest_trap(otmp, FINGER);
  1590.                 } else {
  1591.                 You("disarm it!");
  1592.                 otmp->otrapped = 0;
  1593.                 }
  1594.             } else pline("That %s was not trapped.", doname(otmp));
  1595.             return(1);
  1596.             } else {
  1597.             You("find no traps on the %s.", xname(otmp));
  1598.             return(1);
  1599.             }
  1600.         }
  1601.         if ((ttmp = t_at(x,y)) && ttmp->tseen)
  1602.         You("cannot disable this trap.");
  1603.         else
  1604.         You("know of no traps here.");
  1605.         return(0);
  1606.     }
  1607.  
  1608.     if (!IS_DOOR(levl[x][y].typ)) {
  1609.         if ((ttmp = t_at(x,y)) && ttmp->tseen)
  1610.         You("cannot disable that trap.");
  1611.         else
  1612.         You("know of no traps there.");
  1613.         return(0);
  1614.     }
  1615.  
  1616.     switch (levl[x][y].doormask) {
  1617.         case D_NODOOR:
  1618.         You("%s no door there.", Blind ? "feel" : "see");
  1619.         return(0);
  1620.         case D_ISOPEN:
  1621.         pline("This door is safely open.");
  1622.         return(0);
  1623.         case D_BROKEN:
  1624.         pline("This door is broken.");
  1625.         return(0);
  1626.     }
  1627.  
  1628.     if ((levl[x][y].doormask & D_TRAPPED && !confused &&
  1629.          rn2(MAXLEVEL+2-dlevel) < 10)
  1630.         || confused && !rn2(3)) {
  1631.         You("find a trap on the door!  Disarm it? ");
  1632.         if (ynq() != 'y') return(1);
  1633.         if (levl[x][y].doormask & D_TRAPPED) {
  1634.             ch = 15 +
  1635.              (pl_character[0] == 'R') ? u.ulevel*3 :
  1636.              u.ulevel;
  1637.             if(confused || Fumbling || rnd(75+dlevel/2) > ch) {
  1638.                 You("set it off!");
  1639.                 b_trapped("door");
  1640.             } else
  1641.                 You("disarm it!");
  1642.             levl[x][y].doormask &= ~D_TRAPPED;
  1643.         } else pline("This door was not trapped.");
  1644.         return(1);
  1645.     } else {
  1646.         You("find no traps on the door.");
  1647.         return(1);
  1648.     }
  1649. }
  1650.  
  1651. /* only called when the player is doing something to the chest directly */
  1652. boolean
  1653. chest_trap(obj, bodypart)
  1654. register struct obj *obj;
  1655. register int bodypart;
  1656. {
  1657.     register struct obj *otmp,*otmp2;
  1658.     char    buf[80];
  1659.  
  1660.     if(Luck > -13 && rn2(13+Luck) > 7) return FALSE;
  1661.  
  1662.     otmp = obj;
  1663.     switch(rn2(20) ? ((Luck >= 13) ? 0 : rn2(13-Luck)) : rn2(26)) {
  1664.         case 25:
  1665.         case 24:
  1666.         case 23:
  1667.         case 22:
  1668.         case 21:
  1669.             pline("The %s explodes!", xname(obj));
  1670.             Sprintf(buf, "exploding %s", xname(obj));
  1671.  
  1672.             delete_contents(obj);
  1673.             for(otmp = level.objects[u.ux][u.uy];
  1674.                             otmp; otmp = otmp2) {
  1675.                 otmp2 = otmp->nexthere;
  1676.                 delobj(otmp);
  1677.             }
  1678.  
  1679.             losehp(d(6,6), buf, KILLED_BY_AN);
  1680.             wake_nearby();
  1681.             return TRUE;
  1682.         case 20:
  1683.         case 19:
  1684.         case 18:
  1685.         case 17:
  1686.             pline("A cloud of noxious gas billows from the %s.",
  1687.                   xname(obj));
  1688.             poisoned("gas cloud", A_STR, "cloud of poison gas",15);
  1689.             break;
  1690.         case 16:
  1691.         case 15:
  1692.         case 14:
  1693.         case 13:
  1694.             You("feel a needle prick your %s.",body_part(bodypart));
  1695.             poisoned("needle", A_CON, "poison needle",10);
  1696.             break;
  1697.         case 12:
  1698.         case 11:
  1699.         case 10:
  1700.         case 9:
  1701.             pline("A tower of flame erupts from the %s",
  1702.                   xname(obj));
  1703.             if(Fire_resistance) {
  1704.                 shieldeff(u.ux, u.uy);
  1705.                 You("don't seem to be affected.");
  1706.             } else    losehp(d(4, 6), "tower of flame", KILLED_BY_AN);
  1707.             destroy_item(SCROLL_SYM, AD_FIRE);
  1708. #ifdef SPELLS
  1709.             destroy_item(SPBOOK_SYM, AD_FIRE);
  1710. #endif
  1711.             destroy_item(POTION_SYM, AD_FIRE);
  1712.             break;
  1713.         case 8:
  1714.         case 7:
  1715.         case 6:
  1716.             You("are jolted by a surge of electricity!");
  1717.             if(Shock_resistance)  {
  1718.                 shieldeff(u.ux, u.uy);
  1719.                 You("don't seem to be affected.");
  1720.             } else    losehp(d(4, 4), "electric shock", KILLED_BY_AN);
  1721.             destroy_item(RING_SYM, AD_ELEC);
  1722.             destroy_item(WAND_SYM, AD_ELEC);
  1723.             break;
  1724.         case 5:
  1725.         case 4:
  1726.         case 3:
  1727.             pline("Suddenly you are frozen in place!");
  1728.             nomul(-d(5, 6));
  1729.             nomovemsg = "You can move again.";
  1730.             break;
  1731.         case 2:
  1732.         case 1:
  1733.         case 0:
  1734.             pline("A cloud of %s gas billows from the %s",
  1735.                   hcolor(), xname(obj));
  1736.             if(!Stunned)
  1737.                 if (Hallucination)
  1738.                 pline("What a groovy feeling!");
  1739.                 else
  1740.                 You("stagger and your vision blurs...");
  1741.             make_stunned(HStun + rn1(7, 16),FALSE);
  1742.             make_hallucinated(Hallucination + rn1(5, 16),FALSE);
  1743.             break;
  1744.         default: impossible("bad chest trap");
  1745.             break;
  1746.     }
  1747.     bot();             /* to get immediate botl re-display */
  1748.     otmp->otrapped = 0;        /* these traps are one-shot things */
  1749.  
  1750.     return FALSE;
  1751. }
  1752.  
  1753. #endif /* OVLB */
  1754. #ifdef OVL2
  1755.  
  1756. void
  1757. wake_nearby() {            /* Wake up nearby monsters. */
  1758.     register struct monst *mtmp;
  1759.  
  1760.     for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  1761.         if(dist(mtmp->mx,mtmp->my) < u.ulevel*20) {
  1762.         if(mtmp->msleep)  mtmp->msleep = 0;
  1763.         if(mtmp->mtame)   EDOG(mtmp)->whistletime = moves;
  1764.         }
  1765.     }
  1766. }
  1767.  
  1768. #endif /* OVL2 */
  1769. #ifdef OVL0
  1770.  
  1771. struct trap *
  1772. t_at(x,y)
  1773. register int x, y;
  1774. {
  1775.     register struct trap *trap = ftrap;
  1776.     while(trap) {
  1777.         if(trap->tx == x && trap->ty == y) return(trap);
  1778.         trap = trap->ntrap;
  1779.     }
  1780.     return((struct trap *)0);
  1781. }
  1782.  
  1783. #endif /* OVL0 */
  1784. #ifdef OVLB
  1785.  
  1786. void
  1787. deltrap(trap)
  1788. register struct trap *trap;
  1789. {
  1790.     register struct trap *ttmp;
  1791.  
  1792.     if(trap == ftrap)
  1793.         ftrap = ftrap->ntrap;
  1794.     else {
  1795.         for(ttmp = ftrap; ttmp->ntrap != trap; ttmp = ttmp->ntrap) ;
  1796.         ttmp->ntrap = trap->ntrap;
  1797.     }
  1798.     free((genericptr_t) trap);
  1799. }
  1800.  
  1801. void
  1802. b_trapped(item)        /* used for doors. can be used */
  1803. register const char *item;    /* for anything else that opens */
  1804. {
  1805.     register int dmg = rnd(5+(dlevel < 5 ? dlevel : 2+dlevel/2));
  1806.  
  1807.     pline("KABOOM!!  The %s was booby-trapped!", item);
  1808.     if(u.ulevel < 4 && dlevel < 3 && !rnl(3))
  1809.         You("are shaken, but luckily unhurt.");        
  1810.     else losehp(dmg, "explosion", KILLED_BY_AN);
  1811.     make_stunned(HStun + dmg, TRUE);
  1812. }
  1813.  
  1814. /* Monster is hit by trap. */
  1815. /* Note: doesn't work if both obj and d_override are null */
  1816. STATIC_OVL boolean
  1817. thitm(tlev, mon, obj, d_override)
  1818. register int tlev;
  1819. register struct monst *mon;
  1820. register struct obj *obj;
  1821. int d_override;
  1822. {
  1823.     register int strike;
  1824.     register boolean trapkilled = FALSE;
  1825.  
  1826.     if (d_override) strike = 1;
  1827.     else if (obj) strike = (mon->data->ac + tlev + obj->spe <= rnd(20));
  1828.     else strike = (mon->data->ac + tlev <= rnd(20));
  1829.  
  1830.     /* Actually more accurate than thitu, which doesn't take
  1831.      * obj->spe into account.
  1832.      */
  1833.     if(!strike) {
  1834.         if (cansee(mon->mx, mon->my))
  1835.             pline("%s is almost hit by %s!", Monnam(mon),
  1836.                                 doname(obj));
  1837.     } else {
  1838.         int dam = 1;
  1839.  
  1840.         if (obj && cansee(mon->mx, mon->my))
  1841.             pline("%s is hit by %s!", Monnam(mon), doname(obj));
  1842.         if (d_override) dam = d_override;
  1843.         else if (obj) {
  1844.             dam = dmgval(obj, mon->data);
  1845.             if (dam < 1) dam = 1;
  1846.         }
  1847.         if ((mon->mhp -= dam) <= 0) {
  1848.             int xx = mon->mx;
  1849.             int yy = mon->my;
  1850.  
  1851.             if (cansee(mon->mx, mon->my))
  1852.                 pline("%s is killed!", Monnam(mon));
  1853.             else if (mon->mtame)
  1854.     You("have a sad feeling for a moment, then it passes.");
  1855.             mondied(mon);
  1856.             newsym(xx, yy);
  1857.             trapkilled = TRUE;
  1858.         }
  1859.     }
  1860.     if (obj && (!strike || d_override)) {
  1861.         place_object(obj, mon->mx, mon->my);
  1862.         obj->nobj = fobj;
  1863.         fobj = obj;
  1864.         stackobj(fobj);
  1865.     } else if (obj) free ((genericptr_t)obj);
  1866.  
  1867.     return trapkilled;
  1868. }
  1869.  
  1870. boolean
  1871. unconscious()
  1872. {
  1873.     return (multi < 0 && (!nomovemsg ||
  1874.         !strncmp(nomovemsg,"You wake", 8) ||
  1875.         !strncmp(nomovemsg,"You awake", 9) ||
  1876.         !strncmp(nomovemsg,"You regain con", 15) ||
  1877.         !strncmp(nomovemsg,"You are consci", 15)));
  1878. }
  1879.  
  1880. #endif /* OVLB */
  1881.